<?php

class Media_Filesystem
{

	/**
	 * @param string $path
	 * @return string
	 */
	public static function buildBreadcrumb($path)
	{
		$request = Zend_Controller_Front::getInstance()->getRequest();
		$controller = $request->getControllerName();
		$action = $request->getActionName();
		$segments = WSB_Div::explode('/', $path);
		$lastSegment = array_pop($segments);
		$firstSegment = array_shift($segments);
		$links = array();
		$folder = '';
		$pathSeparator = '';
		foreach($segments AS $segment) {
			$folder .= $pathSeparator . $segment;
			// Url
			if($controller == 'upload') {
				$url = Media_Url::uploadListUrl($folder);
			} elseif($controller == 'trash') {
				$url = Media_Url::trashListUrl($folder);
			}elseif($action == 'browser') {
				$url = Media_Url::fileBrowserUrl($folder);
			} elseif($action == 'fckeditor') {
				$url = Media_Url::fileFckeditorUrl($folder);
			} else {
				$url = Media_Url::fileListUrl($folder);
			}
			$links[] = WSB_Controller_Url::getHtmlLink($segment, $url);
			$pathSeparator = '/';
		}
		// Url
		$folder = '';
		if($controller == 'upload') {
			$url = Media_Url::uploadListUrl($folder);
		} elseif($controller == 'trash') {
			$url = Media_Url::trashListUrl($folder);
		} elseif($action == 'browser') {
			$url = Media_Url::fileBrowserUrl($folder);
		} elseif($action == 'fckeditor') {
			$url = Media_Url::fileFckeditorUrl($folder);
		} else {
			$url = Media_Url::fileListUrl($folder);
		}
		if(!empty($firstSegment)) {
			array_unshift($links, WSB_Controller_Url::getHtmlLink($firstSegment, $url));
		}
		array_push($links, $lastSegment);
		return implode(' / ', $links);
	}

	/**
	 * @return string
	 */
	public static function getMediaFolderPath()
	{
		$config = Zend_Registry::get('Zend_Config');
		$path = WSB_PATH . $config->file->filePath;
		return WSB_Div::trimTrailingSlash($path);
	}

	/**
	 * @return string
	 */
	public static function getTrashFolderPath()
	{
		$config = Zend_Registry::get('Zend_Config');
		$path = WSB_PATH . $config->file->trashPath;
		return WSB_Div::trimTrailingSlash($path);
	}

	/**
	 * @param string $path
	 * @return string
	 */
	public static function sanitizePath($path)
	{
		// .. und \ unterdruecken
		$path = str_replace(array('..', '\\'), '', $path);
		// Mehrere / loeschen
		return preg_replace('#/+#', '/', $path);
	}

	/**
	 * @param string $dirname
	 * @return string
	 */
	public static function filterDirname($dirname)
	{
		$dirname = utf8_decode($dirname);
		$dirname = str_replace(' ', '-', $dirname);
		$dirname = ereg_replace("[^A-Za-z0-9_-]", '', $dirname);
		return $dirname;
	}

	/**
	 * @param string $filename
	 * @return string
	 */
	public static function filterFilename($filename)
	{
		$filename = utf8_decode($filename);
		$filename = str_replace(' ', '-', $filename);
		return ereg_replace("[^A-Za-z0-9\._-]", '', $filename);
	}

	/**
	 * Erstelle ein neues Verzeichnis innerhalb des aktuellen Verzeichnis.
	 *
	 * @param string $name
	 */
	public function createDir($name)
	{
		$dir = $this->getFilePath().DIRECTORY_SEPARATOR.$name;
		$config = Zend_Registry::get('Zend_Config');
		$mode = $config->file->folderCreateMask;
		umask(0);
		mkdir($dir, $mode);
	}

	/**
	 * Rekursives Loeschen aller Verzeichnisse und Dateien innerhalb von $dir.
	 *
	 * @param string $dir
	 */
	public function deleteRecursive($dir)
	{
		$dir = WSB_Div::trimTrailingSlash($dir);
		static $root;
		if(is_null($root)) {
			$root = $dir;
		}
		$contents = scandir($dir);
		foreach($contents as $item) {
			$path = $dir . '/' . $item;
			if(is_dir($path) && $item != '.' && $item != '..') {
				$this->deleteRecursive($path);
			}
			elseif(file_exists($path) && $item != '.' && $item != '..') {
				unlink($path);
			}
		}
		if($root != $dir) {
			rmdir($dir);
		}
	}

	/**
	 * Erstelle Pfadsegmente $segmentsWithinDir innerhalb eines Verzeichnisses $dir.
	 *
	 * @param string $dir
	 * @param string $segmentsWithinDir
	 * @return string
	 */
	public function makeDirSegments($dir, $segmentsWithinDir)
	{
		$config = Zend_Registry::get('Zend_Config');
		$mode = $config->file->folderCreateMask;
		// Zielordner fuer alle Segmente erstellen
		// Nach dem foreach-Block enthaelt die
		// Variable $dstPath den Zielordner.
		$segments = WSB_Div::explode('/', $segmentsWithinDir);
		$dstPath = $dir;
		foreach($segments AS $segment) {
			$dstPath .= $segment . '/';
			if(!is_dir($dstPath)) {
				umask(0);
				mkdir($dstPath, $mode);
			}
		}
		return $dstPath;
	}

	/**
	 * Datei in den Papierkorb verschieben.
	 * Eine Datei aus der Dateiablage wird in den Papierkorb verschoben.
	 * Falls es eine gleichnamige Datei schon gibt, wird diese mit einem
	 * Zeitstempel versehen.
	 *
	 * @param string $relMediaFilePath
	 */
	public function moveToTrash($relMediaFilePath)
	{

		$dirname = WSB_Div::dirname($relMediaFilePath);
		$basename = basename($relMediaFilePath);

		$config = Zend_Registry::get('Zend_Config');
		$mediaPath = WSB_PATH . $config->file->filePath;
		$trashPath = WSB_PATH . $config->file->trashPath;

		$this->makeDirSegments($trashPath, $dirname);

		$src = $mediaPath . $relMediaFilePath;
		$dst = $trashPath . $relMediaFilePath;

		if(is_dir($src)) {
			rmdir($src);
		} else {

			// Falls es ein gleichnamiges File im Papierkorb gibt, wird
			// ein Dateinamen inkl. Zeitstempel erstellt. Anschliessend
			// wird das File verschoben.
			if(is_file($dst)) {
				$dst = $trashPath . $dirname . '/' . $this->_addTimestamp($basename);
			}
			// File verschieben
	 		rename($src, $dst);
		}

	}

	/**
	 * Datei wiederherstellen.
	 * Eine Datei wird vom Papierkorb in die Dateiablage verschoben. Ein Zeitstempel im
	 * Dateiname wird entfernt.
	 *
	 * @param string $relTrashFilePath	Relativer Filepfad ab dem Trashverzeichnis.
	 */
	public function restoreFile($relTrashFilePath)
	{

		$dirname = WSB_Div::dirname($relTrashFilePath);
		$basename = basename($relTrashFilePath);

		$config = Zend_Registry::get('Zend_Config');
		$mediaPath = WSB_PATH . $config->file->filePath;
		$trashPath = WSB_PATH . $config->file->trashPath;

		$this->makeDirSegments($mediaPath, $dirname);

		$src = $trashPath . $relTrashFilePath;
		$dst = $mediaPath . $dirname . '/' . $this->_removeTimestamp($basename);
		// File verschieben
		rename($src, $dst);

	}

	/**
	 * Dem Dateinamen wird ein Zeitstemptel YYYMMDDHHIISS hinzugefuegt.
	 * Bsp: dateiname.doc --> dateiname.20070404102030.doc
	 *
	 * @param string $filename
	 * @return string
	 */
	private function _addTimestamp($filename)
	{
		$info = pathinfo($filename);
		$extension = $info['extension'];
		$basename = substr($filename, 0, (strlen($extension)+1)*-1);
		return $basename . '.' . date('YmdHis') . '.' . $extension;
	}

	/**
	 * Ein vorhandener Zeitstempel wird aus dem Dateinamen entfernt.
	 * Bsp: dateiname.20070404102030.doc --> dateiname.doc
	 *
	 * @param string $filename
	 * @return string
	 */
	private function _removeTimestamp($filename)
	{
		$parts = WSB_Div::explode('.', $filename);
		$timestamp = '';
		$index = count($parts)-2;
		if(isset($parts[$index])) {
			$timestamp = $parts[$index];
			if(preg_match('#[0-9]{14}#', $timestamp)) {
				unset($parts[$index]);
			}
		}
		return implode('.', $parts);
	}

}
